<?php

/**
 * 框架类
 *
 */
final class B
{

    /**
     * 名称
     *
     */
    const NAME = 'website';

    /**
     * 根目录名称
     *
     */
    const PATHNAME = 'rzyx';

    /**
     * 作者
     *
     */
    const AUTHOR = 'wangx';

    /**
     * 版本号
     *
     */
    const VERSION = '1.2.b';


    /**
     * 唯一实例
     *
     * @access private
     * @staticvar
     * @var object
     */
    private static $_instance;

    /**
     * 是否CLI模式
     *
     * @access static
     * @var bool
     */
    static $_cli = false;

    /**
     * 取得唯一实例
     *
     * 只能从此处实例化
     *
     * @access public
     * @static
     * @param mixed $call 调用参数
     * @return object
     */
    static function i($_cli = false)
    {
        self::$_cli = (boolean)$_cli;
        if (is_null(self::$_instance)){
            self::$_instance = new self();
        }
        return self::$_instance;
    }

    /**
     * 构造函数
     *
     * 设置各路径, 当前调用标志, 重置请求数据
     * 此处设置为私有方法, 为了保证只执行一次
     *
     * @access private
     */
    private function __construct()
    {
        $this->_components = array(
            'config'   => array(null, 0),
            'plugin'   => array(null, 0),
            'mode'     => array(null, 0),
            'view'     => array(null, 1),
            'global'   => array(null, 0),
            'language' => array(null, 0),
            'cache'    => array(null, 1),
            'database' => array(null, 1),
        );
        //框架路径
        $path = $bpath = '';
        $path = dirname(__FILE__);
        foreach (explode(DIRECTORY_SEPARATOR, $path) as $v) {
            $bpath .= $v.DIRECTORY_SEPARATOR;
            if ($v == self::PATHNAME) {
                break;
            }
        }
        require_once($path. '/exception.php');
        require_once($path. '/plugin/loader.php');
        BException::report();
        BLoader::aliase(BLoader::ALIASE_PROJECT, rtrim($bpath, DIRECTORY_SEPARATOR));//根目录别名
        BLoader::aliase(BLoader::ALIASE_FRAMEWORK, $path);//框架目录别名
        BLoader::aliase(BLoader::ALIASE_CALL, dirname(current(end(debug_backtrace()))));//工作目录别名
        //cli模式
        $this->plugin->setServerCli(self::cli());
        //if (!BLoader::Import('>/config') && !class_exists(BLoader::ClassName('>/config'), false)) {
        BLoader::Import('>/config');
        //}
        BLoader::instance('../plugin/domain');
        //设置时区
        $this->plugin->time->setTimezone();
        $this->plugin->trace;
        $this->plugin->time->setTime('systemStartTime');
        if (!self::cli()) {
	        //观察者模式
	        $censor = $this->config->censor;
	        $now_censor_val = $this->plugin->cookie->get($censor['user']);
	        define('USER_CENSOR', $now_censor_val && $now_censor_val == $censor['key']);
        } else {
            define('USER_CENSOR', false);
        }
        define('D_DEBUG', $this->config->debug);
    }

    /**
     * 判断是否为cli模式
     *
     * @access public
     * @static
     * @return boolean
     */
    static function cli()
    {
        return self::$_cli;
    }

    public function cache ()
    {
        return $this->mode->cache->engine('memcached')->pick()->signal( USER_CENSOR ? BMode_cache::SIGNAL_EXPIRE : BMode_cache::SIGNAL_NORMAL);
    }

    public function database ()
    {
        return $this->mode->database;
    }
    /**
     * 模板引擎
     *
     * @access private
     * @return object
     */
    private function view()
    {
        return $this->mode->view->pick();
    }

    /**
     * 模型调用
     *
     * @access public
     * @param string $name 变量名
     * @return mixed
     */
    function __get($name)
    {
        if (is_null($this->_components[$name])){
            throw new BException(1000, $name);
        }
        $instance = &$this->_components[$name][0];
        if (is_null($instance)){
            list(,$dispatch) = $this->_components[$name];
            if ($dispatch && method_exists($this, $name)){
                //是否派遣给相关方法处理
                $instance = $this->$name();
            } else {
                $instance = BLoader::instance("../$name");
            }
        }
        return $instance ? $instance : null;
    }

    /**
     * 析构
     *
     * @access public
     */
    function __destruct()
    {
        $time = $this->plugin->time;
        $time->setTime('systemEndTime');
        $queryTime = $time->setTime('systemStartTime', 'systemEndTime', 3);
        if ($queryTime > 2 && (D_DEBUG || USER_CENSOR)) {
            $trace = $this->plugin->trace;
            $data = $_SERVER['REQUEST_URI'] . 'queryTime:['. $queryTime.'s ]'. 'countSQL:['.$trace->N('db_query').']  '. 'SqlQueryTime:['.$trace->N('db_query_time') .'s ]' .PHP_EOL;
            $this->plugin->trace->save(BPlugin_trace::FILE, BLoader::PathName('./data/log/')."_count.log", $data);
        }
        return true;
    }

    /**
     * 预处理行为
     *
     * @access public
     */
    function pretreat()
    {
        $pretreat = BLoader::PathName('>/incldue/init.php');
        if (!is_file($pretreat)) {
        	foreach (array_reverse(BLoader::familyTree()) as $v) {
        		if (is_file($v . BLoader::SPACE_DIR .'include'. BLoader::SPACE_DIR .'init.php')) {
        			$pretreat = $v . BLoader::SPACE_DIR .'include'. BLoader::SPACE_DIR .'init.php';
        			break;
        		}
        	}
        }
        return is_file($pretreat) ? $pretreat : '' ;
    }

}

?>
